package com.econ.powercloud.ems.service.biz;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.econ.powercloud.common.base.facade.enums.StatusType;
import com.econ.powercloud.common.base.facade.exception.CommonRuntimeException;
import com.econ.powercloud.common.base.facade.pojo.MsgResult;
import com.econ.powercloud.common.base.facade.pojo.PageResult;
import com.econ.powercloud.common.base.facade.util.JacksonUtil;
import com.econ.powercloud.ems.common.enums.*;
import com.econ.powercloud.ems.config.EMSStaticMap;
import com.econ.powercloud.ems.constant.SysConstant;
import com.econ.powercloud.ems.dal.entity.*;
import com.econ.powercloud.ems.pojo.*;
import com.econ.powercloud.ems.pojo.requestVO.EmsIssueInitRequestVO;
import com.econ.powercloud.ems.service.dao.*;
import com.econ.powercloud.ems.service.common.QueryFlashDataCommonService;
import com.econ.powercloud.ems.util.GridLogUtil;
import com.econ.powercloud.ems.util.TimeUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author jwc
 * @date 2022/08/03
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class EmsGridService {

    private final EmsDeviceDAO emsDeviceDAO;
    private final EmsPeakShiftDAO emsPeakShiftDAO;
    private final EmsGridRecordDAO emsGridRecordDAO;
    private final EmsGridProcessGroupDAO emsGridProcessGroupDAO;
    private final EmsGridProcessNodeDAO emsGridProcessNodeDAO;
    private final EmsGridProcessStepDAO emsGridProcessStepDAO;
    private final EmsGridRecordGroupDAO emsGridRecordGroupDAO;
    private final EmsGridRecordNodeDAO emsGridRecordNodeDAO;
    private final EmsGridRecordStepDAO emsGridRecordStepDAO;
    private final EmsGridDitConfigDAO emsGridDitConfigDAO;
    private final EmsEnergyStationDAO emsEnergyStationDAO;
    private final AuthUserDAO authUserDAO;

    private final EmsYkYtIssueService emsYkYtIssueService;
    private final EnergyScheduleService energyScheduleService;
    private final QueryFlashDataCommonService queryFlashDataCommonService;
    private final IotProductModuleDAO iotProductModuleDAO;
    private final EmsEnergyEquipmentDAO emsEnergyEquipmentDAO;
    @Resource(name="asyncPoolTaskExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    public List<EmsGirdPcuMonitorVO> getPcuMonitor(String stationId){
        List<EmsGridDitConfig> ditConfigs = emsGridDitConfigDAO.selectByStationId(stationId);
        if(CollectionUtils.isEmpty(ditConfigs)){
            return Collections.emptyList();
        }
        List<EmsGirdPcuMonitorVO> result = Lists.newArrayList();
        //获取该储能站下的所有设备
        List<EmsDevice> allDeviceCode = emsDeviceDAO.selectByEnergyStationId(stationId);
        Map<String,EmsDevice> deviceMap = allDeviceCode.stream().collect(Collectors.toMap(EmsDevice::getDeviceCode,d->d,(p1,p2)->p1));
        //获取该储能站下的产品的模块信息
        List<String> productKeys = allDeviceCode.stream().filter(d->d.getProductKey() != null).map(EmsDevice::getProductKey).collect(Collectors.toList());
        //产品模块map，key: productKet + . + moduleCode, value: 模块名称
        Map<String,String> productModuleSyncMap = iotProductModuleDAO.selectByProductKeys(productKeys).stream().collect(Collectors.toMap(d->d.getProductKey() + SysConstant.SPOT + d.getModuleCode(),d->d.getModuleName()));
        //获取储能装置信息
        Map<String,String> equipmentMap = emsEnergyEquipmentDAO.selectByStationIds(Lists.newArrayList(stationId)).stream().collect(Collectors.toMap(d->d.getEnergyEquipmentId(),d->d.getEnergyEquipmentName()));
        //拼接查询的实时数据
        List<QueryDataVO> queryDataVOS = Lists.newArrayList();
        ditConfigs.stream().forEach(d->{
            EmsDevice emsDevice = deviceMap.get(d.getDeviceCode());
            queryDataVOS.add(QueryDataVO.builder()
                    .pid(d.getRunModelPid()).deviceCode(d.getDeviceCode()).initDeviceCode(emsDevice.getInitDeviceCode())
                    .dit(d.getRunModelPid().replace(emsDevice.getInitDeviceCode() + SysConstant.SPOT,""))
                    .build());
            queryDataVOS.add(QueryDataVO.builder()
                    .pid(d.getOffGirdRunPid()).deviceCode(d.getDeviceCode()).initDeviceCode(emsDevice.getInitDeviceCode())
                    .dit(d.getOffGirdRunPid().replace(emsDevice.getInitDeviceCode() + SysConstant.SPOT,""))
                    .build());
            queryDataVOS.add(QueryDataVO.builder()
                    .pid(d.getOnGirdRunPid()).deviceCode(d.getDeviceCode()).initDeviceCode(emsDevice.getInitDeviceCode())
                    .dit(d.getOnGirdRunPid().replace(emsDevice.getInitDeviceCode() + SysConstant.SPOT,""))
                    .build());

        });
        List<FlashDataVO> flashDataVOS = queryFlashDataCommonService.getFlashData(queryDataVOS);
        Map<String,FlashDataVO> flashDataMap = flashDataVOS.stream().collect(Collectors.toMap(FlashDataVO::getPid,d->d,(p1,p2)->p1));
        ditConfigs.stream().forEach(d->{
            EmsDevice emsDevice = deviceMap.get(d.getDeviceCode());
            EmsDevice initDeviceCode = EMSStaticMap.moduleCodeToDeviceMap.get(emsDevice.getInitDeviceCode() + SysConstant.SPOT + "def");
            result.add(EmsGirdPcuMonitorVO.builder()
                    .deviceCode(d.getDeviceCode())
                    .energyEquipmentId(d.getEnergyEquipmentId())
                    .energyEquipmentName(equipmentMap.get(d.getEnergyEquipmentId()))
                    .initDeviceCode(emsDevice.getInitDeviceCode())
                    .initDeviceName(initDeviceCode == null?null:initDeviceCode.getDeviceName())
                    .moduleCode(emsDevice.getModuleCode())
                    .moduleName(productModuleSyncMap.get(emsDevice.getProductKey() + SysConstant.SPOT +emsDevice.getModuleCode()))
                    .runModelFlashVO(this.getFlashVO(d.getRunModelPid(),d.getDeviceCode(),flashDataMap))
                    .offGirdRunFlashVO(this.getFlashVO(d.getOffGirdRunPid(),d.getDeviceCode(),flashDataMap))
                    .onGirdRunFlashVO((this.getFlashVO(d.getOnGirdRunPid(),d.getDeviceCode(),flashDataMap)))
                    .build());
        });
        return result;
    }

    public EmsGridRecordVO getLeastGirdStatusByStationId(String energyStationId){
        EmsGridRecord gridRecord = emsGridRecordDAO.selectLeast(energyStationId);
        if(gridRecord == null){
            return null;
        }
        return JacksonUtil.convertToObj(gridRecord, EmsGridRecordVO.class);
    }

    /**
     * 获取流程状态值与最新的组合记录的id
     * @param recordId 流程记录id
     * @return vo
     */
    public EmsGridStatusAndGroupVO getStatusAndGroupId(Long recordId){
        EmsGridRecord record = emsGridRecordDAO.getById(recordId);
        EmsGridRecordGroup latestRecordGroup = emsGridRecordGroupDAO.selectLatestByRecordId(recordId);
        Long recordGroupId = latestRecordGroup == null ? null : latestRecordGroup.getId();
        EmsGridStatusAndGroupVO vo = new EmsGridStatusAndGroupVO()
                .setStatus(record.getStatus())
                .setRecordGroupId(recordGroupId);
        return vo;
    }

    public PageResult<List<EmsGridRecordVO>> listPage(String energyStationId, Integer pageNo, Integer pageSize) {
        Page<EmsGridRecord> page = emsGridRecordDAO.selectPage(energyStationId, pageNo, pageSize);
        List<EmsGridRecordVO> list = JacksonUtil.convertToList(page.getRecords(), EmsGridRecordVO.class);
        //根据userId获取到userName
        List<AuthUser> users = authUserDAO.list();
        Map<String,String> userMap = CollectionUtils.isEmpty(users)? Maps.newHashMap():users.stream().collect(Collectors.toMap(AuthUser::getId,AuthUser::getName));
        list.forEach(vo -> {
            vo.setTypeName(GridTypeEnum.getDescFromCode(vo.getType()));
            vo.setStatusName(GridRecordStatusEnum.fromCode(vo.getStatus()));
            vo.setUserName(userMap.get(vo.getCreatedBy()));
        });
        return PageResult.<List<EmsGridRecordVO>>builder().data(list)
                .pageNo((int) page.getCurrent()).totalCount((int) page.getTotal()).build();
    }

    /**
     * 根据记录id获取操作记录的详情
     * @param recordId
     * @return
     */
    public EmsGridRecordDetailsVO getRecordDetails(Long recordId) {
        EmsGridRecord record = emsGridRecordDAO.getById(recordId);
        EmsGridRecordDetailsVO recordDetailsVO = JacksonUtil.convertToObj(record, EmsGridRecordDetailsVO.class);
        recordDetailsVO.setTypeName(GridTypeEnum.getDescFromCode(record.getType()));
        //获取所有子组合记录的详情
        List<EmsGridRecordGroup> recordGroupList = emsGridRecordGroupDAO.selectByRecordId(recordId);
        //获取所有子节点记录的详情
        List<EmsGridRecordNode> recordNodeList = emsGridRecordNodeDAO.selectByRecordGroupIds(recordGroupList.stream().map(EmsGridRecordGroup::getId).collect(Collectors.toList()));
        Map<Long,List<EmsGridRecordNode>> recordNodeMapByRecordGroupId = recordNodeList.stream().collect(Collectors.groupingBy(d->d.getRecordGroupId()));
        //获取所有子步骤记录的详情
        List<EmsGridRecordStep> recordStepList = emsGridRecordStepDAO.selectByRecordNodeIds(recordNodeList.stream().map(EmsGridRecordNode::getId).collect(Collectors.toList()));
        Map<Long,List<EmsGridRecordStep>> recordStepMapByRecordNodeId = recordStepList.stream().collect(Collectors.groupingBy(d->d.getRecordNodeId()));
        //获取所有的步骤配置详情
        List<EmsGridProcessStep> processStepList = emsGridProcessStepDAO.selectListByProcessStepIds(recordStepList.stream().map(EmsGridRecordStep::getProcessStepId).collect(Collectors.toList()));
        Map<Long,EmsGridProcessStep> processStepMap = processStepList.stream().collect(Collectors.toMap(EmsGridProcessStep::getId,d->d,(p1,p2)->p1));
        List<EmsGridRecordGroupVO> recordGroupVOList = Lists.newArrayList();

        for (EmsGridRecordGroup recordGroup : recordGroupList) {
            recordGroupVOList.add(this.getRecordGroupDetails(recordGroup,recordNodeMapByRecordGroupId,recordStepMapByRecordNodeId,processStepMap));
        }
        recordDetailsVO.setRecordGroupVOList(recordGroupVOList);
        return recordDetailsVO;
    }

    public EmsGridRecordGroupVO getRecordGroupDetailById(Long recordGroupId){
        EmsGridRecordGroup recordGroup = emsGridRecordGroupDAO.getById(recordGroupId);
        //获取所有子节点记录的详情
        List<EmsGridRecordNode> recordNodeList = emsGridRecordNodeDAO.selectByRecordGroupId(recordGroupId);
        Map<Long,List<EmsGridRecordNode>> recordNodeMapByRecordGroupId = recordNodeList.stream().collect(Collectors.groupingBy(d->d.getRecordGroupId()));
        //获取所有子步骤记录的详情
        List<EmsGridRecordStep> recordStepList = emsGridRecordStepDAO.selectByRecordNodeIds(recordNodeList.stream().map(EmsGridRecordNode::getId).collect(Collectors.toList()));
        Map<Long,List<EmsGridRecordStep>> recordStepMapByRecordNodeId = recordStepList.stream().collect(Collectors.groupingBy(d->d.getRecordNodeId()));
        //获取所有的步骤配置详情
        List<EmsGridProcessStep> processStepList = emsGridProcessStepDAO.selectListByProcessStepIds(recordStepList.stream().map(EmsGridRecordStep::getProcessStepId).collect(Collectors.toList()));
        Map<Long,EmsGridProcessStep> processStepMap = processStepList.stream().collect(Collectors.toMap(EmsGridProcessStep::getId,d->d,(p1,p2)->p1));
        return this.getRecordGroupDetails(recordGroup,recordNodeMapByRecordGroupId,recordStepMapByRecordNodeId,processStepMap);
    }

    public EmsGridRecordGroupVO getRecordGroupDetails(EmsGridRecordGroup recordGroup, Map<Long,List<EmsGridRecordNode>> recordNodeMapByRecordGroupId,
                                                      Map<Long,List<EmsGridRecordStep>> recordStepMapByRecordNodeId,
                                                      Map<Long,EmsGridProcessStep> processStepMap) {
        EmsGridRecordGroupVO recordGroupVO = JacksonUtil.convertToObj(recordGroup, EmsGridRecordGroupVO.class);
        //获取该组合记录下的所有节点记录
        List<EmsGridRecordNode> recordNodeList = recordNodeMapByRecordGroupId.get(recordGroup.getId());
        recordNodeList = recordNodeList == null ? Lists.newArrayList(): recordNodeList;
        List<EmsGridRecordNodeVO> recordNodeVOList = Lists.newArrayList();
        for (EmsGridRecordNode recordNode : recordNodeList) {
            recordNodeVOList.add(this.getRecordNodeDetails(recordNode, recordStepMapByRecordNodeId, processStepMap));
        }
        if (!recordGroupVO.getStatus().equals(GridRecordStatusEnum.UNCONFIRMED.getCode())) {
            //待确认才有按钮
            recordGroupVO.setButtonName(StringUtils.EMPTY);
        }
        recordGroupVO.setRecordNodeVOList(recordNodeVOList);
        return recordGroupVO;
    }

    public EmsGridRecordNodeVO getRecordNodeDetails(EmsGridRecordNode recordNode, Map<Long,List<EmsGridRecordStep>> recordStepMapByRecordNodeId,
                                                    Map<Long,EmsGridProcessStep> processStepMap) {
        EmsGridRecordNodeVO recordNodeVO = JacksonUtil.convertToObj(recordNode, EmsGridRecordNodeVO.class);
        //获取该节点记录下的所有步骤记录
        List<EmsGridRecordStep> recordStepList = recordStepMapByRecordNodeId.get(recordNode.getId());
        List<EmsGridRecordStepVO> recordStepVOList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(recordStepList)) {
            for (EmsGridRecordStep recordStep : recordStepList) {
                recordStepVOList.add(this.getRecordStepDetails(recordStep, processStepMap));
            }
        }
        recordNodeVO.setRecordStepVOList(recordStepVOList);
        return recordNodeVO;
    }

    public EmsGridRecordStepVO getRecordStepDetails(EmsGridRecordStep recordStep,Map<Long,EmsGridProcessStep> processStepMap) {
        EmsGridRecordStepVO recordStepVO = JacksonUtil.convertToObj(recordStep, EmsGridRecordStepVO.class);
        EmsGridProcessStep processStep = processStepMap.get(recordStep.getProcessStepId());
        if (recordStepVO.getStatus().equals(GridRecordStatusEnum.UNCONFIRMED.getCode())) {
            //待确认才有按钮
            recordStepVO.setButtonName(processStep.getButtonName());
        }
        return recordStepVO;
    }

    @Transactional(rollbackFor = Exception.class)
    public void stop(Long recordId) {
        log.info("手动终止流程，流程id:{}", recordId);
        EmsGridRecord record = emsGridRecordDAO.getById(recordId);
        //终止流程
        this.stopRecord(record);
        EmsGridRecordGroup recordGroup = emsGridRecordGroupDAO.selectLatestByRecordId(recordId);
        if (recordGroup != null) {
            //终止组合
            this.stopRecordGroup(recordGroup, record);
            EmsGridRecordNode recordNode = emsGridRecordNodeDAO.selectLatestByGroupId(recordGroup.getId());
            if (recordNode != null) {
                //终止节点
                this.stopRecordNode(recordNode);
                EmsGridRecordStep recordStep = emsGridRecordStepDAO.selectLatestByNodeId(recordNode.getId());
                if (recordStep != null) {
                    //终止步骤
                    this.stopRecordStep(recordStep);
                }
            }
        }
    }

    /**
     * 终止流程记录
     * @param record 流程记录
     */
    public void stopRecord(EmsGridRecord record) {
        record.setStatus(GridRecordStatusEnum.TERMINATED.getCode())
                .setEndTime(new Date());
        emsGridRecordDAO.updateById(record);
    }

    /**
     * 终止组合
     * @param recordGroup 组合记录
     */
    public void stopRecordGroup(EmsGridRecordGroup recordGroup, EmsGridRecord record) {
        if (recordGroup.getStatus().equals(GridRecordStatusEnum.UNCONFIRMED.getCode())) {
            recordGroup.setLogs(recordGroup.getLogs() + "\n" + GridLogUtil.getTerminateLog(record.getType()));
        } else {
            recordGroup.setLogs(GridLogUtil.getTerminateLog(record.getType()));
        }
        recordGroup.setStatus(GridRecordStatusEnum.TERMINATED.getCode())
                .setEndTime(new Date());
        emsGridRecordGroupDAO.updateById(recordGroup);
    }

    /**
     * 终止节点
     * @param recordNode 节点记录
     */
    public void stopRecordNode(EmsGridRecordNode recordNode) {
        recordNode.setStatus(GridRecordStatusEnum.TERMINATED.getCode())
                .setEndTime(new Date());
        emsGridRecordNodeDAO.updateById(recordNode);
    }

    /**
     * 终止步骤
     * @param recordStep 步骤记录
     */
    public void stopRecordStep(EmsGridRecordStep recordStep) {
        recordStep.setStatus(GridRecordStatusEnum.TERMINATED.getCode())
                .setEndTime(new Date());
        emsGridRecordStepDAO.updateById(recordStep);
    }

    /**
     * 继续执行组合
     * @param recordGroupId 组合记录id
     */
    public void confirmGroup(Long recordGroupId) {
        EmsGridRecordGroup recordGroup = emsGridRecordGroupDAO.getById(recordGroupId);
        EmsGridRecord record = emsGridRecordDAO.getById(recordGroup.getRecordId());
        //校验状态
        if (!record.getStatus().equals(GridRecordStatusEnum.IN_PROGRESS.getCode())) {
            //流程是进行中状态，才可以操作
            throw new CommonRuntimeException(StatusType.FAIL, "操作失败，该流程状态为：" + GridRecordStatusEnum.fromCode(record.getStatus()));
        }
        if (!recordGroup.getStatus().equals(GridRecordStatusEnum.UNCONFIRMED.getCode())) {
            throw new CommonRuntimeException(StatusType.FAIL, "操作失败，该组合状态为：" + GridRecordStatusEnum.fromCode(recordGroup.getStatus()));
        }
        //组合状态改为失败
        this.failRecordGroup(recordGroup);
        //是否有下个组合
        threadPoolTaskExecutor.execute(() -> this.hasNextProcessGroup(record, recordGroup));
    }

    /**
     * 通过步骤id执行步骤
     * @param recordStepId
     */
    public void executeStepById(Long recordStepId) {
        EmsGridRecordStep recordStep = emsGridRecordStepDAO.getById(recordStepId);
        EmsGridRecordNode recordNode = emsGridRecordNodeDAO.getById(recordStep.getRecordNodeId());
        EmsGridRecordGroup recordGroup = emsGridRecordGroupDAO.getById(recordNode.getRecordGroupId());
        EmsGridRecord record = emsGridRecordDAO.getById(recordGroup.getRecordId());
        //校验状态
        if (!record.getStatus().equals(GridRecordStatusEnum.IN_PROGRESS.getCode())) {
            throw new CommonRuntimeException(StatusType.FAIL, "操作失败，该流程状态为：" + GridRecordStatusEnum.fromCode(record.getStatus()));
        }
        if (!recordStep.getStatus().equals(GridRecordStatusEnum.UNCONFIRMED.getCode())) {
            throw new CommonRuntimeException(StatusType.FAIL, "执行失败，该步骤状态为：" + GridRecordStatusEnum.fromCode(recordStep.getStatus()));
        }
        recordStep.setStatus(GridRecordStatusEnum.SUCCESS.getCode())
                .setEndTime(new Date());
        emsGridRecordStepDAO.updateById(recordStep);
        threadPoolTaskExecutor.execute(() -> this.hasNextProcessStep(recordNode, recordStep));
    }

    /**
     * 离网
     * @param energyStationId 储能站id
     * @return 记录id
     */
    @Transactional(rollbackFor = Exception.class)
    public Long offGrid(String energyStationId) {
        Integer inProgressCount = emsGridRecordDAO.selectCountByStationIdAndStatus(energyStationId, GridRecordStatusEnum.IN_PROGRESS.getCode());
        if(inProgressCount > 0) {
            throw new CommonRuntimeException(StatusType.FAIL, "操作失败，当前正在执行并离网操作");
        }
        //新增一条record
        EmsGridRecord record = new EmsGridRecord()
                .setEnergyStationId(energyStationId)
                .setType(GridTypeEnum.OFF_GRID.getCode())
                .setStatus(GridRecordStatusEnum.IN_PROGRESS.getCode());
        emsGridRecordDAO.save(record);
        //查找流程的第一个组合
        EmsGridProcessGroup processGroup = emsGridProcessGroupDAO.selectByStationIdAndTypeAndOrderNum(energyStationId, GridTypeEnum.OFF_GRID.getCode(), 1);
        this.createNotStartGroup(processGroup, record);
        return record.getId();
    }

    @Transactional(rollbackFor = Exception.class)
    public Long onGrid(String energyStationId) {
        Integer inProgressCount = emsGridRecordDAO.selectCountByStationIdAndStatus(energyStationId, GridRecordStatusEnum.IN_PROGRESS.getCode());
        if(inProgressCount > 0) {
            throw new CommonRuntimeException(StatusType.FAIL, "操作失败，当前正在执行并离网操作");
        }
        //新增一条record
        EmsGridRecord record = new EmsGridRecord()
                .setEnergyStationId(energyStationId)
                .setType(GridTypeEnum.ON_GRID.getCode())
                .setStatus(GridRecordStatusEnum.IN_PROGRESS.getCode());
        emsGridRecordDAO.save(record);
        //查找流程的第一个模块
        EmsGridProcessGroup processGroup = emsGridProcessGroupDAO.selectByStationIdAndTypeAndOrderNum(energyStationId, GridTypeEnum.ON_GRID.getCode(), 1);
        this.createNotStartGroup(processGroup, record);
        return record.getId();
    }

    /**
     * 执行组合
     * @param recordGroup 组合记录
     */
    public void executeGroup(EmsGridRecordGroup recordGroup) {
        EmsGridRecord record = emsGridRecordDAO.getById(recordGroup.getRecordId());
        //先校验状态
        if (!record.getStatus().equals(GridRecordStatusEnum.IN_PROGRESS.getCode())) {
            //流程是进行中状态，才可以执行组合
            return;
        }
        if (!recordGroup.getStatus().equals(GridRecordStatusEnum.NOT_STARTED.getCode())) {
            //组合是未开始状态，才可以执行，防止重复执行
            return;
        }
        recordGroup.setStatus(GridRecordStatusEnum.IN_PROGRESS.getCode())
                .setBeginTime(new Date());
        emsGridRecordGroupDAO.updateById(recordGroup);
        //获取第一个节点
        EmsGridProcessNode firstProcessNode = emsGridProcessNodeDAO.selectByProcessGroupIdAndOrderNum(recordGroup.getProcessGroupId(), 1);
        this.judgeNodeFronts(firstProcessNode, recordGroup);
    }

    /**
     * 执行节点
     * @param recordNode 节点记录
     * @param recordGroup 组合记录
     */
    public void executeNode(EmsGridRecordNode recordNode, EmsGridRecordGroup recordGroup) {
        EmsGridRecord record = emsGridRecordDAO.getById(recordGroup.getRecordId());
        //先校验状态
        if (!record.getStatus().equals(GridRecordStatusEnum.IN_PROGRESS.getCode())) {
            //流程是进行中状态，才可以执行组合
            return;
        }
        if (!recordNode.getStatus().equals(GridRecordStatusEnum.NOT_STARTED.getCode())) {
            //节点是未开始状态，才可以执行，防止重复执行
            return;
        }
        recordNode.setStatus(GridRecordStatusEnum.IN_PROGRESS.getCode());
        emsGridRecordNodeDAO.updateById(recordNode);
        //获取第一个步骤
        EmsGridProcessStep firstProcessStep = emsGridProcessStepDAO.selectByProcessNodeIdAndOrderNum(recordNode.getProcessNodeId(), 1);
        EmsGridRecordStep firstRecordStep = this.createNotStartRecordStep(firstProcessStep, recordNode);
        this.executeStep(firstRecordStep, recordNode);
    }

    /**
     * 执行步骤
     * @param recordStep 步骤记录
     * @param recordNode 节点记录
     */
    public void executeStep(EmsGridRecordStep recordStep, EmsGridRecordNode recordNode) {
        log.info("执行方法executeStep，步骤id:{}", recordStep.getId());
        EmsGridRecordGroup recordGroup = emsGridRecordGroupDAO.getById(recordNode.getRecordGroupId());
        EmsGridRecord record = emsGridRecordDAO.getById(recordGroup.getRecordId());
        //先校验状态
        if (!record.getStatus().equals(GridRecordStatusEnum.IN_PROGRESS.getCode())) {
            //流程是进行中状态，才可以执行组合
            return;
        }
        if (!recordStep.getStatus().equals(GridRecordStatusEnum.NOT_STARTED.getCode())) {
            //当前步骤是未开始状态，才可以执行，防止重复执行
            return;
        }
        //将当前步骤状态改为进行中
        recordStep.setStatus(GridRecordStatusEnum.IN_PROGRESS.getCode());
        recordStep.setBeginTime(new Date());
        emsGridRecordStepDAO.updateById(recordStep);
        EmsGridProcessStep processStep = emsGridProcessStepDAO.getById(recordStep.getProcessStepId());
        Integer operationType = processStep.getOperationType();
        Integer actionType = processStep.getActionType();
        Pair<Integer, String> pair = null;
        if(operationType.equals(GridOperationTypeEnum.SEND_YK_YT.getCode())){
            //下发遥控/遥调
            if (actionType.equals(GridActionTypeEnum.YK.getCode()) || actionType.equals(GridActionTypeEnum.YT.getCode())) {
                //下发遥控或遥调
                pair = sendYkYtOrder(recordStep);
                if(null != pair.getLeft()) {
                    //下发成功
                    recordStep.setSyncMsgId(pair.getLeft());
                    //赋值Logs
                    recordStep.setLogs(GridLogUtil.getIssuedYkYtLog(true,processStep.getStepName(),pair.getRight()));
                } else {
                    //下发失败
                    recordStep.setStatus(GridRecordStatusEnum.FAIL.getCode())
                            .setEndTime(new Date())
                            .setLogs(GridLogUtil.getIssuedYkYtLog(false,processStep.getStepName(),pair.getRight()));
                }
            }
        } else if (operationType.equals(GridOperationTypeEnum.SEND_ORDER.getCode())) {
            //下发命令
            if (actionType.equals(GridActionTypeEnum.PEAK_SHIFT.getCode())){
                //下发移峰填谷
                //获取下发的值，是启用还是停止
                Integer sendVal = processStep.getSendVal().intValue();
                if (sendVal.equals(EnabledType.NOT_ENABLE.getCode())) {
                    //停止移峰填谷
                    EmsPeakShift emsPeakShift = emsPeakShiftDAO.selectByStationIdAndEnable(record.getEnergyStationId(), processStep.getDit(), EnabledType.ENABLE.getCode());
                    if (null == emsPeakShift) {
                        //已经是停止状态，无需下发停止命令
                        recordStep.setStatus(GridRecordStatusEnum.SUCCESS.getCode())
                                .setEndTime(new Date())
                                .setLogs(String.format("%s，%s，已停止，无需下发命令", TimeUtil.dateToStrLong(new Date()),processStep.getStepName()));
                    } else {
                        try{
                            pair = energyScheduleService.peakShiftEnabled(emsPeakShift.getPeakShiftId(), EnabledType.NOT_ENABLE.getCode());
                            recordStep.setSyncMsgId(pair.getLeft())
                                    .setStopPeakShiftId(emsPeakShift.getPeakShiftId())
                                    .setStatus(GridRecordStatusEnum.SUCCESS.getCode())
                                    .setEndTime(new Date())
                                    .setLogs(GridLogUtil.getIssuedCommandLog(true,processStep.getStepName(),pair.getRight()));
                        } catch (Exception e) {
                            log.info("下发移峰填谷抛出异常:{}", e.getMessage());
                            recordStep.setStatus(GridRecordStatusEnum.FAIL.getCode())
                                    .setEndTime(new Date())
                                    .setLogs(GridLogUtil.getIssuedCommandLog(false,processStep.getStepName(),null));
                        }
                    }
                } else {
                    //启用移峰填谷
                    //先查找出上次停止的移峰填谷的id
                    EmsGridRecordStep lastStopPeakShiftRecordStep = emsGridRecordStepDAO.selectLastStopPeakShift(record.getEnergyStationId(), processStep.getDit());
                    if (lastStopPeakShiftRecordStep == null) {
                        //未找到上次停止的移峰填谷策略
                        recordStep.setStatus(GridRecordStatusEnum.SUCCESS.getCode())
                                .setEndTime(new Date())
                                .setLogs(String.format("%s，%s，未找到上次停止的移峰填谷策略，无需下发命令", TimeUtil.dateToStrLong(new Date()),processStep.getStepName()));
                    } else {
                        try {
                            pair = energyScheduleService.peakShiftEnabled(lastStopPeakShiftRecordStep.getStopPeakShiftId(), EnabledType.ENABLE.getCode());
                            if(null == pair) {
                                //已经是启用状态，无需下发停止命令
                                //赋值logs
                                recordStep.setLogs(String.format("%s，%s，已启用，无需下发命令", TimeUtil.dateToStrLong(new Date()),processStep.getStepName()))
                                        .setStatus(GridRecordStatusEnum.SUCCESS.getCode())
                                        .setEndTime(new Date());
                            } else {
                                recordStep.setSyncMsgId(pair.getLeft())
                                        .setStatus(GridRecordStatusEnum.SUCCESS.getCode())
                                        .setEndTime(new Date())
                                        .setLogs(GridLogUtil.getIssuedCommandLog(true,processStep.getStepName(),pair.getRight()));
                            }
                        } catch (Exception e){
                            //下发失败了
                            log.info("下发移峰填谷抛出异常:{}", e.getMessage());
                            recordStep.setStatus(GridRecordStatusEnum.FAIL.getCode())
                                    .setEndTime(new Date())
                                    .setLogs(GridLogUtil.getIssuedCommandLog(false,processStep.getStepName(),null));
                        }
                    }
                }
            }
        } else if (operationType.equals(GridOperationTypeEnum.CHECK_DIT.getCode())) {
            //查询点号
            Pair<Boolean,String> result;
            //获取轮序查询的结果
            result = this.judgeFlashDataByTimeOut(processStep);
            log.info("查询点号：{}，是否满足预期值：{}，查询值：{}", processStep.getDit(), result.getLeft(), result.getRight());
            recordStep.setStatus(result.getLeft()?GridRecordStatusEnum.SUCCESS.getCode():GridRecordStatusEnum.FAIL.getCode())
                    .setEndTime(new Date())
                    .setCheckDitVal(result.getRight())
                    .setLogs(GridLogUtil.queryFlashDataLog(result.getLeft(),processStep.getStepName(),processStep.getDit(),result.getRight(),processStep.getCheckExpectedVal()));
        } else if(operationType.equals(GridOperationTypeEnum.TRIGGER.getCode())){
            //手动触发
            recordStep.setStatus(GridRecordStatusEnum.UNCONFIRMED.getCode())
                    .setEndTime(new Date())
                    .setLogs(String.format("%s", processStep.getStepName()));
        }
        emsGridRecordStepDAO.updateById(recordStep);
        //步骤是否执行成功
        this.checkRecordStepStatus(recordStep);
    }

    /**
     * 当前流程完成/结束（状态改为成功）
     * @param record 流程记录
     */
    public void finishRecord(EmsGridRecord record){
        //结束当前流程，状态改为成功
        record.setStatus(GridRecordStatusEnum.SUCCESS.getCode())
                .setEndTime(new Date());
        emsGridRecordDAO.updateById(record);
    }

    /**
     * 是否有下个组合
     * @param record 流程记录
     * @param recordGroup 组合记录
     */
    public void hasNextProcessGroup(EmsGridRecord record, EmsGridRecordGroup recordGroup) {
        EmsGridProcessGroup nextProcessGroup = emsGridProcessGroupDAO.selectByStationIdAndTypeAndOrderNum(record.getEnergyStationId(), record.getType(), recordGroup.getOrderNum() + 1);
        if (nextProcessGroup !=null) {
            //有下个组合，则创建并执行
            this.createNotStartGroup(nextProcessGroup, record);
        } else {
            //没有下个组合了，则流程完成、结束（状态为成功）
            this.finishRecord(record);
        }
    }

    /**
     * 是否有下个节点
     * @param recordGroup 组合记录
     * @param recordNode 节点记录
     */
    public void hasNextProcessNode(EmsGridRecordGroup recordGroup, EmsGridRecordNode recordNode) {
        EmsGridProcessNode nextProcessNode = emsGridProcessNodeDAO.selectByProcessGroupIdAndOrderNum(recordGroup.getProcessGroupId(), recordNode.getOrderNum() + 1);
        if (nextProcessNode != null) {
            //有下个节点
            this.judgeNodeFronts(nextProcessNode, recordGroup);
        } else {
            //没有下个节点
            this.judgeAllNodeRecord(recordGroup);
        }
    }

    /**
     * 是否有下个步骤，并返回
     * @param recordNode 组合记录
     * @param recordStep 节点记录
     * @return 下个步骤
     */
    public void hasNextProcessStep(EmsGridRecordNode recordNode, EmsGridRecordStep recordStep) {
        EmsGridRecordGroup recordGroup = emsGridRecordGroupDAO.getById(recordNode.getRecordGroupId());
        EmsGridProcessStep nextProcessStep = emsGridProcessStepDAO.selectByProcessNodeIdAndOrderNum(recordNode.getProcessNodeId(), recordStep.getOrderNum() + 1);
        if (nextProcessStep !=null) {
            //有下个步骤，则执行
            EmsGridRecordStep nextRecordStep = this.createNotStartRecordStep(nextProcessStep, recordNode);
            this.executeStep(nextRecordStep, recordNode);
        } else {
            //没有下个步骤了
            log.info("没有下个步骤");
            //当前节点执行完成
            this.finishRecordNode(recordNode);
            //是否有下个节点
            this.hasNextProcessNode(recordGroup, recordNode);
        }
    }

    /**
     * 步骤是否执行完成（成功状态）
     * 成功执行下一节点,失败执行重试机制
     * @param recordStep 步骤记录
     */
    public void checkRecordStepStatus(EmsGridRecordStep recordStep) {
        log.info("checkRecordStepStatus方法执行，步骤id为：{}", recordStep.getId());
        EmsGridProcessStep processStep = emsGridProcessStepDAO.getById(recordStep.getProcessStepId());
        EmsGridRecordNode recordNode = emsGridRecordNodeDAO.getById(recordStep.getRecordNodeId());
        EmsGridRecordGroup recordGroup = emsGridRecordGroupDAO.getById(recordNode.getRecordGroupId());
        if (recordStep.getStatus().equals(GridRecordStatusEnum.SUCCESS.getCode())) {
            //成功
            //有没有下个步骤了
            this.hasNextProcessStep(recordNode, recordStep);
        } else if (recordStep.getStatus().equals(GridRecordStatusEnum.FAIL.getCode())){
            //失败
            if (processStep.getOperationType().equals(GridOperationTypeEnum.SEND_YK_YT.getCode()) ||
                    processStep.getOperationType().equals(GridOperationTypeEnum.SEND_ORDER.getCode())) {
                //下发指令，需要判断是否达到执行次数上限
                Integer retryCount = processStep.getRetryCount();
                List<EmsGridRecordStep> recordStepList = emsGridRecordStepDAO.selectByRecordNodeIdAndOrderNum(recordStep.getRecordNodeId(), recordStep.getOrderNum());
                if (retryCount != null && recordStepList.size() > retryCount) {
                    //达到最大执行次数，不能再重试了，节点失败
                    this.failRecordNode(true,recordNode);
                    this.hasNextProcessNode(recordGroup, recordNode);
                } else {
                    //先创建步骤记录(如果操作类型是查询节点需要手动更改执行类型)
                    EmsGridRecordStep retryRecordStep = this.createNotStartRecordStep(processStep, recordNode);
                    //执行步骤
                    this.executeStep(retryRecordStep, recordNode);
                }
            } else {
                //不需要判断次数，则节点失败
                this.failRecordNode(true,recordNode);
                //recordStep.setLogs("失败了");
                this.hasNextProcessNode(recordGroup, recordNode);

            }
        }
    }

    /**
     * 创建未开始状态的组合记录，并执行组合
     * @param processGroup 组合
     * @param record 流程记录
     */
    public void createNotStartGroup(EmsGridProcessGroup processGroup, EmsGridRecord record) {
        //创建组合的未开始状态的记录
        EmsGridRecordGroup recordGroup = JacksonUtil.convertToObj(processGroup, EmsGridRecordGroup.class);
        recordGroup.setId(null)
                .setRecordId(record.getId())
                .setProcessGroupId(processGroup.getId())
                .setStatus(GridRecordStatusEnum.NOT_STARTED.getCode())
                .setCreateTime(null)
                .setUpdateTime(null);
        emsGridRecordGroupDAO.save(recordGroup);
        //执行组合
        this.executeGroup(recordGroup);
    }

    /**
     * 创建未开始状态的节点记录，并判断节点是否有前置条件
     */
    public void judgeNodeFronts(EmsGridProcessNode processNode, EmsGridRecordGroup recordGroup) {
        log.info("judgeNodeFronts方法执行，节点模板的id为：{}，组合记录的id为：{}", processNode.getId(), recordGroup.getId());
        //创建该节点的未开始状态的记录
        EmsGridRecordNode recordNode = createNotStartRecordNode(processNode, recordGroup);
        //节点是否有前置条件
        String fronts = recordNode.getFronts();
        log.info("节点fronts字段的值为：{}", fronts);
        if (StringUtils.isEmpty(fronts)) {
            //没有前置条件，则直接执行节点
            this.executeNode(recordNode, recordGroup);
        } else {
            //有前置条件，要判断前置条件是否成功。flag：true表示前置条件成功，false表示失败
            boolean flag = true;
            List<Long> frontNodeIdList = Lists.newArrayList(fronts.split(",")).stream().map(Long::valueOf).collect(Collectors.toList());
            List<EmsGridRecordNode> frontRecordNodeList = emsGridRecordNodeDAO.selectByRecordIdAndProcessNodeIds(recordGroup.getRecordId(), frontNodeIdList);
            for (EmsGridRecordNode frontRecordNode : frontRecordNodeList) {
                if (!frontRecordNode.getStatus().equals(GridRecordStatusEnum.SUCCESS.getCode())) {
                    flag = false;
                    break;
                }
            }
            log.info("节点前置条件是否都成功了：{}", flag);
            if (flag) {
                //前置条件都成功了，则执行节点
                this.executeNode(recordNode, recordGroup);
            } else {
                //前置条件失败，则节点失败
                this.failRecordNode(false,recordNode);
                //是否有下个节点
                this.hasNextProcessNode(recordGroup, recordNode);
            }
        }
    }


    /**
     * 检查组合内所有节点的状态
     * @param recordGroup 组合记录
     */
    public void judgeAllNodeRecord(EmsGridRecordGroup recordGroup) {
        EmsGridRecord record = emsGridRecordDAO.getById(recordGroup.getRecordId());
        List<EmsGridRecordNode> recordNodeList = emsGridRecordNodeDAO.selectByRecordGroupId(recordGroup.getId());
        recordGroup.setLogs(GridLogUtil.getCombinationLog(recordGroup.getTitle(),recordNodeList,GridTypeEnum.fromCode(record.getType())));
        int successNum = recordNodeList.stream().filter(d->GridRecordStatusEnum.SUCCESS.getCode().equals(d.getStatus())).collect(Collectors.toList()).size();
        if(successNum == recordNodeList.size()){
            //全部成功
            //组合状态为成功
            this.finishRecordGroup(recordGroup);
            //是否有下个组合
            this.hasNextProcessGroup(record, recordGroup);
        } else if(successNum == 0){
            //全部失败，则组合失败，流程失败、结束
            this.failRecordGroup(recordGroup);
            this.failRecord(record);
        } else {
            //有的成功有的失败
            //组合
            recordGroup.setStatus(GridRecordStatusEnum.UNCONFIRMED.getCode());
            emsGridRecordGroupDAO.updateById(recordGroup);
        }
    }

    /**
     * 当前组合记录完成/结束（状态改为成功）
     * @param recordGroup 组合记录
     */
    public void finishRecordGroup(EmsGridRecordGroup recordGroup){
        recordGroup.setStatus(GridRecordStatusEnum.SUCCESS.getCode())
                .setEndTime(new Date());
        emsGridRecordGroupDAO.updateById(recordGroup);
    }

    /**
     * 当前节点记录完成/结束（状态改为成功）
     * @param recordNode 节点记录
     */
    public void finishRecordNode(EmsGridRecordNode recordNode){
        //赋值logs
        recordNode.setStatus(GridRecordStatusEnum.SUCCESS.getCode())
                .setEndTime(new Date())
                .setLogs(GridLogUtil.getNodeLog(true,true,recordNode.getNodeTitle()));
        emsGridRecordNodeDAO.updateById(recordNode);
    }

    /**
     * 当前流程失败（状态改为失败）
     * @param record 流程记录
     */
    public void failRecord(EmsGridRecord record){
        //结束当前流程，状态改为成功
        record.setStatus(GridRecordStatusEnum.FAIL.getCode())
                .setEndTime(new Date());
        emsGridRecordDAO.updateById(record);
    }

    /**
     * 组合失败
     * @param recordGroup 组合记录
     */
    public void failRecordGroup(EmsGridRecordGroup recordGroup) {
        recordGroup.setStatus(GridRecordStatusEnum.FAIL.getCode())
                .setEndTime(new Date());
        emsGridRecordGroupDAO.updateById(recordGroup);
    }

    /**
     * 节点失败
     * @param recordNode 节点记录
     */
    public void failRecordNode(boolean preconditionCode,EmsGridRecordNode recordNode) {
        //赋值logs
        recordNode.setStatus(GridRecordStatusEnum.FAIL.getCode())
                .setEndTime(new Date())
                .setLogs(GridLogUtil.getNodeLog(preconditionCode,false,recordNode.getNodeTitle()));
        emsGridRecordNodeDAO.updateById(recordNode);
    }

    /**
     * 创建某组合下，未开始状态的节点记录
     * @param processNode 节点模板
     * @param recordGroup 组合记录
     * @return 未开始状态的节点记录
     */
    public EmsGridRecordNode createNotStartRecordNode(EmsGridProcessNode processNode, EmsGridRecordGroup recordGroup) {
        EmsGridRecordNode recordNode = JacksonUtil.convertToObj(processNode, EmsGridRecordNode.class);
        recordNode.setId(null)
                .setProcessNodeId(processNode.getId())
                .setRecordId(recordGroup.getRecordId())
                .setRecordGroupId(recordGroup.getId())
                .setStatus(GridRecordStatusEnum.NOT_STARTED.getCode())
                .setCreateTime(null)
                .setUpdateTime(null);
        emsGridRecordNodeDAO.save(recordNode);
        return recordNode;
    }

    /**
     * 创建某节点下，未开始状态的步骤记录
     * @param processStep 步骤模板
     * @param recordNode 节点记录
     * @return 未开始状态的步骤记录
     */
    public EmsGridRecordStep createNotStartRecordStep(EmsGridProcessStep processStep, EmsGridRecordNode recordNode) {
        EmsGridRecordGroup recordGroup = emsGridRecordGroupDAO.getById(recordNode.getRecordGroupId());
        EmsGridRecord record = emsGridRecordDAO.getById(recordGroup.getRecordId());
        EmsGridRecordStep recordStep = JacksonUtil.convertToObj(processStep, EmsGridRecordStep.class);
        recordStep.setId(null)
                .setEnergyStationId(record.getEnergyStationId())
                .setProcessStepId(processStep.getId())
                .setRecordNodeId(recordNode.getId())
                .setStatus(GridRecordStatusEnum.NOT_STARTED.getCode())
                .setCreateTime(null)
                .setUpdateTime(null);
        emsGridRecordStepDAO.save(recordStep);
        return recordStep;
    }

    /**
     * 判断需要查询的遥测数据是否满足设定的条件(规定时间内轮询查询)
     * @param processStep 节点
     * @return left: 是否满足预期值, right: 查询值
     */
    public Pair<Boolean,String> judgeFlashDataByTimeOut(EmsGridProcessStep processStep){
        log.info("judgeFlashDataByTimeOut，方法执行");
        //超时时间(毫秒)
        int checkTotalTime = processStep.getCheckTotalTime();
        int checkIntervalTime = processStep.getCheckIntervalTime();
        //未超时时间循环查询
        Long startTime = System.currentTimeMillis();
        String val = null;
        Integer measureType = null;
        if (processStep.getActionType().equals(GridActionTypeEnum.YX.getCode())) {
            //遥信
            measureType = MeasureType.yx.getCode();
        } else if (processStep.getActionType().equals(GridActionTypeEnum.YC.getCode())) {
            //遥测
            measureType = MeasureType.yc.getCode();
        }
        while (System.currentTimeMillis() - startTime <= checkTotalTime){
            log.info("judgeFlashDataByTimeOut，进入while循环");
            try {
                FlashDataVO flashDataVO = queryFlashDataCommonService.getFlashDataForDeviceCode(processStep.getInitDeviceCode(),processStep.getDit(), measureType);
                log.info("轮询查询点号:{}，值:{}", flashDataVO.getDit(), flashDataVO.getVal());
                //查询点号并且判断是否满足条件(暂时使用正则表达式来匹配)
                if(flashDataVO != null && flashDataVO.getVal() != null){
                    val = flashDataVO.getVal();
                    if(Double.valueOf(val).equals(Double.valueOf(processStep.getCheckExpectedVal()))){
                        return Pair.of(true,flashDataVO.getVal());
                    }
                }
                Thread.sleep(checkIntervalTime);
            }catch (Exception e){

            }
        }
        return Pair.of(false,val);
    }

    /**
     下发遥控或者遥调指令
     * @param recordStep 步骤记录
     * @return Pair
     */
    public Pair<Integer, String> sendYkYtOrder(EmsGridRecordStep recordStep){
        EmsGridProcessStep processStep = emsGridProcessStepDAO.getById(recordStep.getProcessStepId());
        Integer remoteType = null;
        if(processStep.getActionType().equals(GridActionTypeEnum.YK.getCode())){
            remoteType = RemoteType.YK.getCode();
        } else if (processStep.getActionType().equals(GridActionTypeEnum.YT.getCode())) {
            remoteType = RemoteType.YT.getCode();
        }
        EmsIssueInitRequestVO requestVO = new EmsIssueInitRequestVO().setInitDeviceCode(processStep.getInitDeviceCode())
                .setRemoteType(remoteType).setRemoteDit(processStep.getDit()).setVal(processStep.getSendVal());
        Integer pid = null;
        String json = JSON.toJSONString(requestVO);
        //TODO 检修挂牌确认
        MsgResult<Integer> msgResult = emsYkYtIssueService.modifyYtDataByInit(requestVO,null,false,null);
        if(StatusType.OK.getCode() == msgResult.getStatus()){
            pid = msgResult.getData();
        }
        return Pair.of(pid, json);
    }

    /**
     * 获取配置了并离网流程的储能站
     * @param pageNo
     * @param pageSize
     * @return
     */
    public PageResult<List<ApiDataVO>> getGridEnergyStationList(Integer pageNo, Integer pageSize) {
        List<EmsGridProcessGroup> processModuleList = emsGridProcessGroupDAO.selectGroupByStationId();
        List<String> energyStationIdList = processModuleList.stream().map(EmsGridProcessGroup::getEnergyStationId).collect(Collectors.toList());
        Page<EmsEnergyStation> page = emsEnergyStationDAO.selectListByIdList(energyStationIdList, pageNo, pageSize);
        List<ApiDataVO> apiDataVOS = Lists.newArrayList();
        for (EmsEnergyStation emsEnergyStation : page.getRecords()) {
            apiDataVOS.add(ApiDataVO.builder().code(emsEnergyStation.getEnergyStationId()).name(emsEnergyStation.getEnergyStationName()).build());
        }
        return PageResult.<List<ApiDataVO>>builder().data(apiDataVOS)
                .pageNo((int)page.getCurrent()).totalCount((int)page.getTotal()).build();
    }

    /**
     * 获取实时数据
     * @param flashVOMap : 实时数据查询结果Map
     */
    public FlashVO getFlashVO(String pid,String deviceCode,Map<String,FlashDataVO> flashVOMap){
        if(pid == null){
            return FlashVO.builder().build();
        }
        FlashVO flashVO = FlashVO.builder().pid(pid).initDeviceCode(deviceCode).build();
        //获取查询的实时数据
        FlashDataVO vo = flashVOMap.get(pid);
        if (vo != null) {
            flashVO.setTime(vo.getTime());
            flashVO.setName(vo.getRemark());
            flashVO.setInitDeviceCode(vo.getDeviceCode());
            flashVO.setValue(vo.getVal());
            flashVO.setUnit(vo.getUnit());
        }
        return flashVO;
    }

}
